package test.auth;

import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.abettor.angleworm.auth.HttpsSocketFactory;
import org.abettor.angleworm.util.Configuration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

/**
 * Google登录认证测试程序
 * @author shawn
 *
 */
public class GoogleClientLogin
{
	private static final String LOGIN_URL = Configuration.getGlobalProperty("auth.google.clientLogin.url");
	private static final String CAPTCHA_URL_PREFIX = Configuration.getGlobalProperty("auth.google.clientLogin.captcha.prefix");
	private static final String APP_NAME = Configuration.getGlobalProperty("auth.google.clientLogin.appName");

	public static void main(String[] args) throws HttpException, IOException, URISyntaxException
	{
		//	如果loginToken不为空，则必须进行CAPTCHA验证
		String loginToken = null;
		String loginCaptcha = null;

		while(true)
		{
			//	获取登录信息
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			System.out.print("Google帐号：");
			String account = br.readLine();
			System.out.print("Google密码：");
			String passwd = br.readLine();
			if(loginToken != null)
			{
				System.out.print("验证信息：");
				loginCaptcha = br.readLine();
			}

			if(! account.endsWith("@gmail.com"))
			{
				account += "@gmail.com";
			}

			//	构造登录请求数据包
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			params.add(new NameValuePair("accountType", "GOOGLE"));
			params.add(new NameValuePair("Email", account));
			params.add(new NameValuePair("Passwd", passwd));
			params.add(new NameValuePair("service", "cp"));
			params.add(new NameValuePair("source", APP_NAME));
			if(loginToken != null)
			{
				params.add(new NameValuePair("logintoken", loginToken));
				params.add(new NameValuePair("logincaptcha", loginCaptcha));
			}
			NameValuePair[] paramArray = new NameValuePair[params.size()];
			params.toArray(paramArray);

			//	注册自定义HTTPS链接工厂
			ProtocolSocketFactory psf = new HttpsSocketFactory("google", "www.google.com");
			Protocol protocol = new Protocol("https", psf, 443);
			Protocol.registerProtocol("https", protocol);

			//	构造HTTPS POST请求
			PostMethod pm = new PostMethod(LOGIN_URL);
			pm.addRequestHeader("Content-type", "application/x-www-form-urlencoded");
			pm.setRequestBody(paramArray);

			//	执行HTTPS POST请求
			HttpClient hc = new HttpClient();
			int status = hc.executeMethod(pm);
			if(status == HttpStatus.SC_OK)
			{
				//	获取AuthToken
				InputStream is = pm.getResponseBodyAsStream();
				BufferedReader brResp = new BufferedReader(new InputStreamReader(is));
				String authToken = null;
				String line = brResp.readLine();
				while(line != null)
				{
					if(line.startsWith("Auth"))
					{
						int idx = line.indexOf("=");
						authToken = line.substring(idx + 1);
						break;
					}

					line = brResp.readLine();
				}
				System.out.println("Auth Token: " + authToken);
				break;
			}
			else if(status == HttpStatus.SC_FORBIDDEN)
			{
				//	检查登录失败原因
				Properties prop = new Properties();
				InputStream is = pm.getResponseBodyAsStream();
				BufferedReader brResp = new BufferedReader(new InputStreamReader(is));
				String line = brResp.readLine();
				while(line != null)
				{
					int idx = line.indexOf("=");
					String key = line.substring(0, idx);
					String val = line.substring(idx + 1);
					prop.setProperty(key, val);
	
					line = brResp.readLine();
				}

				String error = prop.getProperty("Error");
				System.out.println("Error Code: " + error);
	
				if("CaptchaRequired".equals(error))
				{
					//	显示CAPTCHA验证信息并准备重新尝试验证身份
					loginToken = prop.getProperty("CaptchaToken");
					String captcha = CAPTCHA_URL_PREFIX + prop.getProperty("CaptchaUrl");
					Desktop desktop = Desktop.getDesktop();
					desktop.browse(new URI(captcha));
				}
				else
				{
					break;
				}
			}

			pm.releaseConnection();
		}
	}
}
